<?php

namespace App\Http\Controllers;

use App\Events\OrderReviewed;
use App\Exceptions\CouponCodeUnavailableException;
use App\Exceptions\InternalException;
use App\Exceptions\InvalidRequestException;
use App\Http\Requests\Admin\HandleRefundRequest;
use App\Http\Requests\ApplyRefundRequest;
use App\Http\Requests\CrowdfundingOrderRequest;
use App\Http\Requests\OrderRequest;
use App\Http\Requests\SendReviewRequest;
use App\Jobs\CloseOrder;
use App\Models\CouponCode;
use App\Models\Order;
use App\Models\ProductSku;
use App\Models\UserAddress;
use App\Services\CartService;
use App\Services\OrderService;
use Carbon\Carbon;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Http\Request;
use DB;

class OrdersController extends Controller
{
    public function index(Request $request)
    {
        $orders = Order::query()
            // 使用 with 方法预加载，避免N + 1问题
            ->with(['items.product','items.productSku'])
            ->where('user_id',$request->user()->id)
            ->orderBy('created_at','desc')
            ->paginate();

        return view('orders.index',['orders'=>$orders]);
    }

    //利用laravel自动解析功能注入CartService类
    public function store(OrderRequest $request, OrderService $orderService)
    {
        $user = $request->user();
        $address = UserAddress::find($request->input('address_id'));
        $coupon = null;

        //如果用户提交了优惠码
        if($code = $request->input('coupon_code')){
            $coupon = CouponCode::where('code',$code)->first();
            if(!$coupon){
                throw new CouponCodeUnavailableException('优惠券不存在');
            }
        }
        return $orderService->store($user,$address,$request->input('remark'),$request->input('items'),$coupon);

    }


    public function show(Order $order, Request $request)
    {
        try {
            $this->authorize('own',$order);
        }catch (AuthenticationException $e){
            throw new InvalidRequestException('权限不足');
        }
        return view('orders.show',['order'=>$order->load(['items.productSku','items.product'])]);
    }


    public function received(Order $order, \App\Http\Requests\Request $request)
    {
        //检验权限
        $this->authorize('own',$order);

        //判断订单发货装是否为已发货
        if($order->ship_status !== Order::SHIP_STATUS_DELIVERED) {
            throw new InvalidRequestException('发货状态不正确');
        }

        //更新发货状态为已收到
        $order->update(['ship_status'=>Order::SHIP_STATUS_RECEIVED]);

        // 返回订单信息
        return $order;
    }

    public function review(Order $order)
    {
        //校验权限
        $this->authorize('own',$order);
        //判断是否已经支付
        if(! $order->paid_at){
            throw new InvalidRequestException('该订单未支付，不可评价');
        }
        //使用load方法加载关联数据，避免N+1性能问题
        return view('orders.review',['order'=>$order->load(['items.productSku','items.product'])]);
    }

    public function SendReview(Order $order, SendReviewRequest $request)
    {
        //校验权限
        $this->authorize('own',$order);
        if(! $order->paid_at){
            throw new InvalidRequestException('该订单未支付，不可评价');
        }
        //判断是否已经评价
        if($order->reviewed) {
            throw new InvalidRequestException('该订单已评价，不可重复提交');
        }
        $reviews = $request->input('reviews');
        //开启事务
        DB::transaction(function () use ($reviews, $order){
            //遍历用户提交的数据
            foreach ($reviews as $review){
                $orderItem = $order->items()->find($review['id']);
                //保存评分和评价
                $orderItem->update([
                    'rating' => $review['rating'],
                    'review' => $review['review'],
                    'reviewed_at' => Carbon::now()
                ]);
            }
            //将订单标记为已评价
            $order->update(['reviewed' => true]);
        });
        event(new OrderReviewed($order));

        return redirect()->back();
    }

    public function applyRefund(Order $order, ApplyRefundRequest $request)
    {
        //校验订单是否属于当前用户
        $this->authorize('own',$order);
        //判断订单是否已付款
        if(! $order->paid_at){
            throw new InvalidRequestException('该订单未支付，不可退款');
        }
        //众筹商品不允许退款
        if($order->type === Order::TYPE_CROWDFUNDING){
            throw new InvalidRequestException('众筹商品不支持退款');
        }
        //判断订单退款状态是否正确
        if($order->refund_status !== Order::REFUND_STATUS_PENDING){
            throw new InvalidRequestException('该订单已经申请过退款，请勿重复申请');
        }
        //将用户输入的退款理由放到订单的 extra 字段中
        $extra = $order->extra ? : [];
        $extra['refund_reason'] = $request->input('reason');
        //将订单退款状态改为已申请退款
        $order->update([
            'refund_status' => Order::REFUND_STATUS_APPLIED,
            'extra' => $extra
        ]);

        return $order;
    }

    public function crowdfunding(CrowdfundingOrderRequest $request, OrderService $orderService)
    {
        $user = $request->user();
        $sku = ProductSku::find($request->input('sku_id'));
        $address = UserAddress::find($request->input('address_id'));
        $amount = $request->input('amount');

        return $orderService->crowdfunding($user,$address,$sku,$amount);
    }


}
